using System.Collections.Generic;
using System.Linq;
using System;

namespace FamilyTreeProject.Collections
{
    // Taken from Rob Conery's Blog post on the ASP.Net MVC PagedList Helper
    // http://blog.wekeroad.com/2007/12/10/aspnet-mvc-pagedlistt/

    /// <summary>
    /// Represents a snapshot of a single page of objects from a data store
    /// </summary>
    /// <typeparam name="T">The type of objects contained in this list</typeparam>
    public class PagedList<T> : List<T>, IPagedList<T>
    {
        #region Constructors

        /// <summary>
        /// Creates a paged list containing objects from the selected enumerable source
        /// </summary>
        /// <param name="source">The <see cref="IEnumerable{T}"/> data store containing objects to be retrieved</param>
        /// <param name="index">The index of the page to retrieve</param>
        /// <param name="pageSize">The size of the page to retrieve</param>
        public PagedList(IEnumerable<T> source, int pageIndex, int pageSize)
        {
            if (pageIndex < 0)
                throw new IndexOutOfRangeException("Index cannot be negative");
            if (pageIndex * pageSize > (source.Count() - 1))
                throw new IndexOutOfRangeException("Index * PageSize cannot be larger than the number of records.");
            this.TotalCount = source.Count();
            this.PageSize = pageSize;
            this.PageIndex = pageIndex;
            this.AddRange(source.Skip(pageIndex * pageSize).Take(pageSize).ToList());
        }

        #endregion

        #region IPagedList Members

        /// <summary>
        /// The total number of objects in the data store
        /// </summary>
        public int TotalCount { get; set; }

        /// <summary>
        /// The index of the page contained in this list
        /// </summary>
        public int PageIndex { get; set; }

        /// <summary>
        /// The size of the page in this list
        /// </summary>
        public int PageSize { get; set; }

        /// <summary>
        /// Gets a boolean indicating if there is a previous page available
        /// </summary>
        public bool HasPreviousPage
        {
            get
            {
                return (PageIndex > 0);
            }
        }

        /// <summary>
        /// Gets a boolean indicating if there is a next page available
        /// </summary>
        public bool HasNextPage
        {
            get
            {
                return ((PageIndex + 1) * PageSize) < TotalCount;
            }
        }        

        #endregion
    }
}
